package com.atguigu.spzx.manager.service.impl;

import com.atguigu.spzx.manager.helper.MenuHelper;
import com.atguigu.spzx.manager.mapper.SysRoleMenuMapper;
import com.atguigu.spzx.manager.service.SysRoleMenuService;
import com.atguigu.spzx.manager.service.SysRoleUserService;
import com.atguigu.spzx.manager.utils.AuthContextUtil;
import com.atguigu.spzx.model.entity.system.SysMenu;
import com.atguigu.spzx.model.entity.system.SysRoleMenu;
import com.atguigu.spzx.model.entity.system.SysRoleUser;
import com.atguigu.spzx.model.entity.system.SysUser;
import com.atguigu.spzx.model.vo.system.SysMenuVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.spzx.manager.service.SysMenuService;
import com.atguigu.spzx.manager.mapper.SysMenuMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Windows
 * @description 针对表【sys_menu(菜单表)】的数据库操作Service实现
 * @createDate 2024-01-29 14:35:18
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu>
        implements SysMenuService {

    @Autowired
    private SysRoleUserService sysRoleUserService;

    @Autowired
    private SysRoleMenuMapper sysRoleMenuMapper;

    @Override
    public List<SysMenu> findNodes() {
        List<SysMenu> sysMenuList = this.list(
                new LambdaQueryWrapper<SysMenu>()
                        // 按照sort升序排
                        .orderBy(true, true, SysMenu::getSortValue)
        );
        if (CollectionUtils.isEmpty(sysMenuList)) {
            return null;
        }

        List<SysMenu> treeList = MenuHelper.buildTree(sysMenuList);
        return treeList;
    }

    @Override
    public List<SysMenuVo> findUserMenuList() {
        // 从user_role关联表获取roleId
        // 从role_menu关联表中获取menuId
        // 改装成SysMenuVo类型的数据并返回
        SysUser sysUser = AuthContextUtil.get();
        List<Long> roleIdList = sysRoleUserService.list(new LambdaQueryWrapper<SysRoleUser>()
                        .eq(SysRoleUser::getUserId, sysUser.getId())).
                stream().map(SysRoleUser::getRoleId).collect(Collectors.toList());

        List<Long> menuIdList = sysRoleMenuMapper.selectList(new LambdaQueryWrapper<SysRoleMenu>()
                        .in(!CollectionUtils.isEmpty(roleIdList),SysRoleMenu::getRoleId, roleIdList))
                .stream().map(SysRoleMenu::getMenuId).collect(Collectors.toList());

        if (CollectionUtils.isEmpty(menuIdList)) {
            return new ArrayList<SysMenuVo>();
        }
        List<SysMenu> menuList = this.list(new LambdaQueryWrapper<SysMenu>()
                .in(SysMenu::getId, menuIdList));

        // 获取树形式
        List<SysMenu> menuTreeList = MenuHelper.buildTree(menuList);

        // 返回VO形式数据
        return buildMenus(menuTreeList);
    }

    @Override
    public void saveSysMenu(SysMenu sysMenu) {
        // 添加新的节点
        this.save(sysMenu);

        // 新添加一个菜单，那么此时就需要将该菜单所对应的父级菜单设置为半开
        updateSysRoleMenuIsHalf(sysMenu) ;
    }

    /**
     * 更新半开状态
     * @param sysMenu
     */
    private void updateSysRoleMenuIsHalf(SysMenu sysMenu) {
        SysMenu parent = this.getById(sysMenu.getParentId());
        if (parent != null) {
            SysRoleMenu sysRoleMenu = new SysRoleMenu();
            sysRoleMenu.setIsHalf(1);
            sysRoleMenuMapper.update(sysRoleMenu, new LambdaQueryWrapper<SysRoleMenu>()
                    .eq(SysRoleMenu::getMenuId,sysMenu.getId()));

            updateSysRoleMenuIsHalf(parent);
        }
    }

    /**
     * 构筑显示对象
     *
     * @param menuTreeList
     * @return
     */
    private List<SysMenuVo> buildMenus(List<SysMenu> menuTreeList) {
        List<SysMenuVo> sysMenuVoList = new LinkedList<>();

        for (SysMenu sysMenu : menuTreeList) {
            SysMenuVo sysMenuVo = new SysMenuVo();
            sysMenuVo.setTitle(sysMenu.getTitle());
            sysMenuVo.setName(sysMenu.getComponent());
            List<SysMenu> children = sysMenu.getChildren();
            // 如果还有子节点，则继续递归构筑
            if (!CollectionUtils.isEmpty(children)) {
                sysMenuVo.setChildren(buildMenus(children));
            }
            sysMenuVoList.add(sysMenuVo);
        }
        return sysMenuVoList;
    }
}




